package com.googlecode.lohr.tools.interpreter;

import java.util.ArrayList;
import java.util.List;

import lohr.lang.dom.ClosureBody;
import lohr.lang.dom.ClosureLiteral;
import lohr.lang.dom.Expression;

/**
 * A closure is simply a list of expressions.
 * When a closure is invoked the expressions are executed in the order in which they were declared.
 * 
 * @author ted.stockwell
 */
public class ClosureImpl extends ObjectImpl {
	
	/**
	 * The list of expressions to execute
	 */
	private List<ExpressionImpl> _expressions= new ArrayList<ExpressionImpl>();

	public ClosureImpl(LohrInterpreter interpreter, ClosureLiteral closure) {
		super(interpreter, interpreter.ClosureType);
		
		ClosureBody body= closure.getClosureBody();
		List<Expression> expressions= body.getExpressions();
		
		for (Expression expression : expressions) {
			_expressions.add(ExpressionImpl.createExpressionImpl(interpreter, expression));
		} 
	}

	@Override
	public ObjectImpl invoke(ObjectImpl invocationContext, Locals arguments) {
		
		/*
		 * Execute each expression in the closure with the given context and arguments
		 */
		ObjectImpl returnValue= null;
		for (ExpressionImpl e : _expressions) {
			returnValue= e.invoke(invocationContext, arguments);
			if (e instanceof MethodReturnImpl)
				break;
		}
		
		// the return value is the value of the last executed expression
		return returnValue;
	}

}
